#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
化学反应过程自动化分析工具
Automated Chemical Process Analyzer

用途：
1. 读取工艺配置文件（YAML/JSON）
2. 进行物料平衡计算
3. 能耗分析
4. 经济性评估
5. 反应动力学模拟
"""

import json
import yaml
import sys
from typing import Dict, List, Any
from pathlib import Path


class ProcessAnalyzer:
    """化学工艺过程分析器"""
    
    def __init__(self, config_file: str):
        """
        初始化分析器
        
        Args:
            config_file: 配置文件路径（支持.yaml或.json）
        """
        self.config_file = Path(config_file)
        self.config = self._load_config()
        
    def _load_config(self) -> Dict:
        """加载配置文件"""
        if not self.config_file.exists():
            raise FileNotFoundError(f"配置文件不存在: {self.config_file}")
        
        if self.config_file.suffix == '.yaml' or self.config_file.suffix == '.yml':
            with open(self.config_file, 'r', encoding='utf-8') as f:
                return yaml.safe_load(f)
        elif self.config_file.suffix == '.json':
            with open(self.config_file, 'r', encoding='utf-8') as f:
                return json.load(f)
        else:
            raise ValueError(f"不支持的文件格式: {self.config_file.suffix}")
    
    def get_project_info(self) -> Dict:
        """获取项目基本信息"""
        return self.config.get('project', {})
    
    def get_chemical_by_id(self, chem_id: str) -> Dict:
        """根据ID获取化学品信息"""
        for chem in self.config['chemicals']['reactants']:
            if chem['id'] == chem_id:
                return chem
        return None
    
    def calculate_material_balance(self, num_batches: int = 1) -> Dict:
        """
        计算物料平衡

        Args:
            num_batches: 批次数

        Returns:
            物料平衡结果
        """
        mb = self.config.get('material_balance', {})

        total_input_cost = sum(item['cost'] for item in mb['inputs']) * num_batches
        total_output_revenue = sum(item['revenue'] for item in mb['outputs']) * num_batches
        total_waste_cost = sum(item.get('treatment_cost', 0) for item in mb['waste']) * num_batches

        # 兼容YAML和JSON格式
        actual_yield = mb.get('actual_yield', 0)
        if isinstance(actual_yield, dict):
            actual_yield = actual_yield.get('value', 0)

        return {
            'batches': num_batches,
            'total_input_cost': total_input_cost,
            'total_output_revenue': total_output_revenue,
            'total_waste_cost': total_waste_cost,
            'gross_profit': total_output_revenue - total_input_cost - total_waste_cost,
            'yield': mb.get('overall_yield', 0),
            'actual_output': actual_yield * num_batches
        }
    
    def calculate_energy_consumption(self, num_batches: int = 1) -> Dict:
        """
        计算能耗

        Args:
            num_batches: 批次数

        Returns:
            能耗分析结果
        """
        energy = self.config.get('energy_analysis', {})

        # 兼容YAML和JSON格式
        total_energy_per_batch = energy.get('total_energy_per_batch', 0)
        if isinstance(total_energy_per_batch, dict):
            total_energy_per_batch = total_energy_per_batch.get('value', 0)

        total_energy_cost = energy.get('total_energy_cost', 0)
        if isinstance(total_energy_cost, dict):
            total_energy_cost = total_energy_cost.get('value', 0)

        electricity_price = energy.get('electricity_price', 0.8)
        if isinstance(electricity_price, dict):
            electricity_price = electricity_price.get('value', 0.8)

        total_energy = total_energy_per_batch * num_batches
        total_cost = total_energy_cost * num_batches

        breakdown = []
        for item in energy.get('breakdown', []):
            breakdown.append({
                'step_id': item['step_id'],
                'energy': item['energy'] * num_batches,
                'percentage': item['percentage'],
                'cost': item['energy'] * electricity_price * num_batches
            })

        return {
            'batches': num_batches,
            'total_energy_kwh': total_energy,
            'total_cost_cny': total_cost,
            'breakdown': breakdown
        }
    
    def analyze_economics(self, num_batches: int = 120) -> Dict:
        """
        经济性分析

        Args:
            num_batches: 年度批次数

        Returns:
            经济性分析结果
        """
        econ = self.config.get('economic_analysis', {})

        # 兼容YAML和JSON格式
        def get_value(obj, default=0):
            if isinstance(obj, dict):
                return obj.get('value', default)
            return obj if obj is not None else default

        # 计算单位成本
        total_cost = get_value(econ.get('costs', {}).get('total', 0))
        annual_output = get_value(econ.get('production_scale', {}).get('annual_output_actual', 0))
        unit_cost = total_cost / annual_output if annual_output > 0 else 0

        return {
            'annual_batches': num_batches,
            'annual_output_kg': annual_output,
            'total_cost_cny': total_cost,
            'unit_cost_cny_per_kg': unit_cost,
            'annual_revenue_cny': get_value(econ.get('revenue', {}).get('annual_sales', 0)),
            'gross_margin': econ.get('profitability', {}).get('gross_margin', 0),
            'net_margin': econ.get('profitability', {}).get('net_margin', 0),
            'roi': econ.get('profitability', {}).get('ROI', 0),
            'payback_period_years': get_value(econ.get('profitability', {}).get('payback_period', 0))
        }
    
    def get_process_steps(self) -> List[Dict]:
        """获取所有工艺步骤"""
        return self.config.get('process_steps', [])
    
    def get_step_by_id(self, step_id: str) -> Dict:
        """根据ID获取工艺步骤"""
        for step in self.get_process_steps():
            if step['step_id'] == step_id:
                return step
        return None
    
    def get_chemical_reactions(self) -> List[Dict]:
        """获取所有化学反应"""
        reactions = []
        for step in self.get_process_steps():
            if 'chemical_reactions' in step:
                for rxn in step['chemical_reactions']:
                    rxn['step_id'] = step['step_id']
                    rxn['step_name'] = step['step_name']
                    reactions.append(rxn)
        return reactions
    
    def analyze_degradation_performance(self, pollutant_id: str = "POLL-001") -> Dict:
        """
        分析污染物降解性能

        Args:
            pollutant_id: 污染物ID

        Returns:
            降解性能分析
        """
        app = self.config.get('application', {})

        # 兼容YAML和JSON格式
        def get_value(obj, default=None):
            if isinstance(obj, dict):
                return obj.get('value', default) if 'value' in obj else obj
            return obj if obj is not None else default

        for deg in app.get('degradation_reactions', []):
            if deg.get('pollutant_id') == pollutant_id:
                perf = deg.get('performance', {})
                return {
                    'pollutant': deg.get('pollutant_name', ''),
                    'initial_concentration': deg.get('initial_concentration', {}),
                    'degradation_rate': perf.get('degradation_rate', 0),
                    'reaction_time': perf.get('reaction_time', {}),
                    'COD_removal': perf.get('COD_removal', 0),
                    'TOC_removal': perf.get('TOC_removal', 0),
                    'mineralization': perf.get('mineralization', 0),
                    'mechanism_steps': len(deg.get('reaction_mechanism', []))
                }
        return None
    
    def generate_report(self) -> str:
        """生成分析报告"""
        project = self.get_project_info()
        mb = self.calculate_material_balance(1)
        energy = self.calculate_energy_consumption(1)
        econ = self.analyze_economics()
        
        report = f"""
{'='*80}
化学工艺过程分析报告
Chemical Process Analysis Report
{'='*80}

项目信息:
  名称: {project['name']}
  代码: {project['code']}
  版本: {project['version']}
  设计产能: {project['target_capacity']} kg/月
  批次规模: {project['batch_size']} kg/批

{'='*80}
物料平衡分析 (单批次):
{'='*80}
  实际产量: {mb['actual_output']:.2f} kg
  总收率: {mb['yield']*100:.1f}%
  原料成本: ¥{mb['total_input_cost']:.2f}
  产品收入: ¥{mb['total_output_revenue']:.2f}
  废物处理: ¥{mb['total_waste_cost']:.2f}
  毛利润: ¥{mb['gross_profit']:.2f}

{'='*80}
能耗分析 (单批次):
{'='*80}
  总能耗: {energy['total_energy_kwh']:.1f} kWh
  电费: ¥{energy['total_cost_cny']:.2f}
  
  各步骤能耗:
"""
        for item in energy['breakdown']:
            report += f"    {item['step_id']}: {item['energy']:.1f} kWh ({item['percentage']*100:.1f}%) - ¥{item['cost']:.2f}\n"
        
        report += f"""
{'='*80}
经济性分析 (年度):
{'='*80}
  年产量: {econ['annual_output_kg']:.0f} kg
  年批次: {econ['annual_batches']} 批
  总成本: ¥{econ['total_cost_cny']:,.0f}
  单位成本: ¥{econ['unit_cost_cny_per_kg']:.2f}/kg
  年收入: ¥{econ['annual_revenue_cny']:,.0f}
  毛利率: {econ['gross_margin']*100:.1f}%
  净利率: {econ['net_margin']*100:.1f}%
  投资回报率: {econ['roi']*100:.1f}%
  回收期: {econ['payback_period_years']:.2f} 年

{'='*80}
化学反应:
{'='*80}
"""
        reactions = self.get_chemical_reactions()
        for rxn in reactions:
            report += f"  [{rxn['step_id']}] {rxn['reaction_name']}\n"
            report += f"    {rxn['reaction_equation']}\n"
            if 'thermodynamics' in rxn:
                thermo = rxn['thermodynamics']
                report += f"    ΔH = {thermo.get('delta_H', 'N/A')} kJ/mol, "
                report += f"ΔG = {thermo.get('delta_G', 'N/A')} kJ/mol\n"
            report += "\n"
        
        # 降解性能
        deg_perf = self.analyze_degradation_performance("POLL-001")
        if deg_perf:
            # 兼容YAML和JSON格式
            init_conc = deg_perf['initial_concentration']
            if isinstance(init_conc, dict):
                init_conc_str = f"{init_conc.get('value', 'N/A')} {init_conc.get('unit', '')}"
            else:
                init_conc_str = f"{init_conc} mg/L"

            rxn_time = deg_perf['reaction_time']
            if isinstance(rxn_time, dict):
                rxn_time_str = f"{rxn_time.get('value', 'N/A')} {rxn_time.get('unit', '')}"
            else:
                rxn_time_str = f"{rxn_time} minutes"

            report += f"""
{'='*80}
污染物降解性能:
{'='*80}
  目标污染物: {deg_perf['pollutant']}
  初始浓度: {init_conc_str}
  降解率: {deg_perf['degradation_rate']*100:.1f}%
  反应时间: {rxn_time_str}
  COD去除率: {deg_perf['COD_removal']*100:.1f}%
  TOC去除率: {deg_perf['TOC_removal']*100:.1f}%
  矿化率: {deg_perf['mineralization']*100:.1f}%
  反应机理步骤: {deg_perf['mechanism_steps']} 步

"""
        
        report += f"{'='*80}\n"
        report += "报告生成完成\n"
        report += f"{'='*80}\n"
        
        return report


def main():
    """主函数"""
    # 默认使用JSON配置文件
    config_file = "react/catalyst_production_process.json"
    
    # 如果命令行提供了参数，使用指定的配置文件
    if len(sys.argv) > 1:
        config_file = sys.argv[1]
    
    print(f"正在加载配置文件: {config_file}")
    
    try:
        analyzer = ProcessAnalyzer(config_file)
        print("✅ 配置文件加载成功\n")
        
        # 生成并打印报告
        report = analyzer.generate_report()
        print(report)
        
        # 保存报告到文件
        report_file = "react/process_analysis_report.txt"
        with open(report_file, 'w', encoding='utf-8') as f:
            f.write(report)
        print(f"\n📄 报告已保存到: {report_file}")
        
    except Exception as e:
        print(f"❌ 错误: {e}")
        sys.exit(1)


if __name__ == "__main__":
    main()

